package com.example.chamberlainserver.Service.impl;

import com.example.chamberlainserver.Entry.User;
import com.example.chamberlainserver.Entry.UserAvailability;
import com.example.chamberlainserver.Service.UserAvailabilityService;
import com.example.chamberlainserver.Service.UserService;
import com.example.chamberlainserver.dto.PageResult;
import com.example.chamberlainserver.dto.TimeSlotResponseDTO;
import com.example.chamberlainserver.mapper.UserAvailabilityMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 用户可用时间服务实现类
 */
@Service
public class UserAvailabilityServiceImpl implements UserAvailabilityService {

    @Autowired
    private UserAvailabilityMapper userAvailabilityMapper;
    
    @Autowired
    private UserService userService;

    @Override
    public boolean addUserAvailability(UserAvailability userAvailability) {
        userAvailability.setId(UUID.randomUUID().toString());
        userAvailability.setCreatedAt(LocalDateTime.now());
        userAvailability.setUpdatedAt(LocalDateTime.now());
        return userAvailabilityMapper.insertUserAvailability(userAvailability) > 0;
    }

    @Override
    @Transactional
    public boolean batchAddUserAvailability(List<UserAvailability> userAvailabilityList) {
        if (userAvailabilityList == null || userAvailabilityList.isEmpty()) {
            return false;
        }
        
        LocalDateTime now = LocalDateTime.now();
        for (UserAvailability userAvailability : userAvailabilityList) {
            userAvailability.setId(UUID.randomUUID().toString());
            userAvailability.setCreatedAt(now);
            userAvailability.setUpdatedAt(now);
        }
        
        return userAvailabilityMapper.batchInsertUserAvailability(userAvailabilityList) > 0;
    }

    @Override
    public UserAvailability getUserAvailabilityById(String id) {
        UserAvailability userAvailability = userAvailabilityMapper.getUserAvailabilityById(id);
        if (userAvailability != null && userAvailability.getUserId() != null) {
            User user = userService.getUserById(userAvailability.getUserId());
            userAvailability.setUser(user);
        }
        return userAvailability;
    }

    @Override
    public List<UserAvailability> getUserAvailabilityByUserId(Integer userId) {
        List<UserAvailability> userAvailabilityList = userAvailabilityMapper.getUserAvailabilityByUserId(userId);
        User user = userService.getUserById(userId);
        
        for (UserAvailability userAvailability : userAvailabilityList) {
            userAvailability.setUser(user);
        }
        
        return userAvailabilityList;
    }

    @Override
    public List<UserAvailability> getAvailableUsersByDayOfWeek(Integer dayOfWeek) {
        List<UserAvailability> userAvailabilityList = userAvailabilityMapper.getAvailableUsersByDayOfWeek(dayOfWeek);
        
        for (UserAvailability userAvailability : userAvailabilityList) {
            if (userAvailability.getUserId() != null) {
                User user = userService.getUserById(userAvailability.getUserId());
                userAvailability.setUser(user);
            }
        }
        
        return userAvailabilityList;
    }

    @Override
    public boolean updateUserAvailability(UserAvailability userAvailability) {
        userAvailability.setUpdatedAt(LocalDateTime.now());
        return userAvailabilityMapper.updateUserAvailability(userAvailability) > 0;
    }

    @Override
    public boolean deleteUserAvailability(String id) {
        return userAvailabilityMapper.deleteUserAvailabilityById(id) > 0;
    }

    @Override
    @Transactional
    public boolean deleteUserAvailabilityByUserId(Integer userId) {
        return userAvailabilityMapper.deleteUserAvailabilityByUserId(userId) > 0;
    }

    @Override
    public PageResult<UserAvailability> getPagedUserAvailabilityList(Map<String, Object> params) {
        // 查询总记录数
        Long total = userAvailabilityMapper.getPagedUserAvailabilityCount(params);
        
        // 查询数据列表
        List<UserAvailability> userAvailabilityList = userAvailabilityMapper.getPagedUserAvailabilityList(params);
        
        // 为每个记录加载用户信息
        for (UserAvailability userAvailability : userAvailabilityList) {
            if (userAvailability.getUserId() != null) {
                User user = userService.getUserById(userAvailability.getUserId());
                userAvailability.setUser(user);
            }
        }
        
        Integer current = (Integer) params.getOrDefault("current", 1);
        Integer pageSize = (Integer) params.getOrDefault("pageSize", 10);
        
        return new PageResult<>(current, pageSize, total, userAvailabilityList);
    }

    @Override
    @Transactional
    public boolean updateUserWeeklyAvailability(Integer userId, List<UserAvailability> weeklyAvailability) {
        // 先删除用户现有的可用时间
        deleteUserAvailabilityByUserId(userId);
        
        // 批量添加新的可用时间
        if (weeklyAvailability != null && !weeklyAvailability.isEmpty()) {
            for (UserAvailability userAvailability : weeklyAvailability) {
                userAvailability.setUserId(userId);
            }
            return batchAddUserAvailability(weeklyAvailability);
        }
        
        return true;
    }
    
    @Override
    public TimeSlotResponseDTO getUserTimeSlots(Integer userId) {
        List<UserAvailability> userAvailabilityList = userAvailabilityMapper.getUserAvailabilityByUserId(userId);
        
        List<TimeSlotResponseDTO.TimeSlotDTO> timeSlots = new ArrayList<>();
        
        // 定义时间段索引映射 - 与前端TimeGrid组件保持一致
        Map<String, Integer> timeSlotIndexMap = new HashMap<>();
        timeSlotIndexMap.put("08:00-10:00", 0);  // 早班1
        timeSlotIndexMap.put("10:00-12:00", 1);  // 早班2
        timeSlotIndexMap.put("12:00-14:00", 2);  // 午班
        timeSlotIndexMap.put("14:00-16:00", 3);  // 下午班1
        timeSlotIndexMap.put("16:00-18:00", 4);  // 下午班2
        timeSlotIndexMap.put("18:00-20:00", 5);  // 晚班1
        timeSlotIndexMap.put("20:00-22:00", 6);  // 晚班2
        
        for (UserAvailability availability : userAvailabilityList) {
            String timeRange = availability.getStartTime() + "-" + availability.getEndTime();
            Integer timeSlotIndex = timeSlotIndexMap.get(timeRange);
            
            if (timeSlotIndex != null) {
                TimeSlotResponseDTO.TimeSlotDTO timeSlot = new TimeSlotResponseDTO.TimeSlotDTO(
                    availability.getDayOfWeek(),
                    timeSlotIndex,
                    availability.getStartTime().toString(),
                    availability.getEndTime().toString(),
                    availability.getIsAvailable()
                );
                timeSlots.add(timeSlot);
            }
        }
        
        return new TimeSlotResponseDTO(timeSlots);
    }
}